home *** CD-ROM | disk | FTP | other *** search
/ More DosGames 2.0 / MORE - Dosgames 2.0 (Software Company)(1994).iso / dosgames / hedge / hedge.c < prev    next >
Text File  |  1994-09-01  |  23KB  |  876 lines

  1. /****************************************************************************\
  2. *                                                                            *
  3. *  Hedge.c                                                                   *
  4. *                                                                            *
  5. *  Copyright 1993 Diana Gruber. All rights reserved.                         *
  6. *                                                                            *
  7. *  This program is copyrighted freeware, distributed with source code.       *
  8. *  Code is provided "as is" without any warranties. You may use portions     *
  9. *  of this code in your own programs as long as you do not use more than     *
  10. *  50% of the code in any one program.                                       *
  11. *                                                                            *
  12. *  This code is provided for instructional purposes. It requires Fastgraph   *
  13. *  or Fastgraph/Light to link.                                               *
  14. *                                                                            *
  15. *  For more information, including the compilation and linking commands for  *
  16. *  all supported compilers, please see the HEDGE.DOC file.                   *
  17. *                                                                            *
  18. \****************************************************************************/
  19.  
  20. #include "defs.h"
  21. #define NMAZES 7
  22.  
  23. /****************************************************************************\
  24. *                                                                            *
  25. *  main -- all functions are in alphabetical order except this one           *
  26. *                                                                            *
  27. \****************************************************************************/
  28.  
  29. void main()
  30. {
  31.    register int i,j;
  32.    int n;
  33.  
  34.    char *maze_name[] =
  35.    {
  36.       "maze001.lev",
  37.       "maze002.lev",
  38.       "maze003.lev",
  39.       "maze004.lev",
  40.       "maze005.lev",
  41.       "maze006.lev",
  42.       "maze007.lev"
  43.    };
  44.  
  45.    /* open the attribute file and read the attributes */
  46.  
  47.    if ((tstream = fopen("hedge.att","rb")) == NULL)
  48.    {
  49.       sprintf(abort_string,"HEDGE.ATT not found.");
  50.       abort_game();
  51.    }
  52.    fread(attributes,sizeof(char),240,tstream);
  53.    fclose(tstream);
  54.  
  55.    /* initialize SVGA graphics */
  56.  
  57.    init_graphics();
  58.    fg_tcmask(1);
  59.  
  60.    intro_screen();
  61.  
  62.    /* load the dub diner file on the hidden page */
  63.  
  64.    fg_setpage(HIDDEN);
  65.    fg_erase();
  66.    fg_move(80,60);
  67.    fg_showpcx("DUBDINER.PCX",2);
  68.  
  69.    /* copy it to the logical page (EMS or XMS) */
  70.  
  71.    fg_copypage(HIDDEN,SPARE);
  72.  
  73.    /* display the maze file on the hidden page */
  74.  
  75.    fg_move(0,0);
  76.    fg_showpcx("HEDGE.PCX",1);
  77.  
  78.    fg_setpage(VISUAL);
  79.    fg_setcolor(0);
  80.    center_string("Please wait...",400,300);
  81.    fg_setcolor(7);
  82.    center_string("Press any key to continue.",400,300);
  83.    fg_waitkey();
  84.  
  85.    for (n = 0; n < NMAZES; n++)
  86.    {
  87.       fg_setrgb(7,63,63,63);
  88.       fg_setrgb(5,63,63,63);
  89.       fg_setrgb(2,63,63,63);
  90.       fg_mousevis(OFF);
  91.       fg_copypage(SPARE,VISUAL);
  92.  
  93.       load_maze(maze_name[n]);
  94.  
  95.       for (i = 0; i <50; i++)
  96.       {
  97.          for (j = 0; j <37; j++)
  98.             visited[i][j] = 0;
  99.       }
  100.  
  101.       for (i = 0; i < 2000; i++)
  102.          path[i] = -1;
  103.       path_index = 1;
  104.  
  105.       flushkey();
  106.       if (n == 0) help_window();
  107.  
  108.       fg_mousevis(ON);
  109.       run_maze();
  110.    }
  111.    quit_graphics();
  112. }
  113.  
  114. /****************************************************************************\
  115. *                                                                            *
  116. *  calc_truepath -- recursive algorithm to solve maze                        *
  117. *                                                                            *
  118. \****************************************************************************/
  119.  
  120. int calc_truepath(int i,int j)
  121. {
  122.    int tile,nexttile;
  123.    int attr,nextattr;
  124.    int x1,x2,y1,y2;
  125.    int found;
  126.    int index;
  127.    int stall_time;
  128.    int left,right,top,bottom;
  129.    int horizontal,vertical;
  130.    int nextcross;
  131.  
  132.    stall_time = clockspeed/4;
  133.    visited[i][j] = TRUE;
  134.    index = path_index;
  135.  
  136.    while(1)
  137.    {
  138.       fg_stall(stall_time);
  139.  
  140.       tile = layout[i][j];
  141.       attr = attributes[tile];
  142.       found = FALSE;
  143.  
  144.       x1 = i*16 + 6;
  145.       x2 = x1 + 4;
  146.       y1 = j*16 + 6;
  147.       y2 = y1 + 4;
  148.  
  149.       left       = attr&LEFT;
  150.       right      = attr&RIGHT;
  151.       top        = attr&TOP;
  152.       bottom     = attr&BOTTOM;
  153.       vertical   = attr&VERTICAL;
  154.       horizontal = attr&HORIZONTAL;
  155.  
  156.       if (horizontal || vertical)
  157.       {
  158.          if (path[index-1] == LEFT || path[index-1] == RIGHT)
  159.          {
  160.             top = FALSE; bottom = FALSE;
  161.          }
  162.          else if (path[index-1] == TOP || path[index-1] == BOTTOM)
  163.          {
  164.             left = FALSE; right = FALSE;
  165.          }
  166.       }
  167.  
  168.       /* check right */
  169.  
  170.       if (j < MAXCOLS-1 && !found && !(path[index-1] == LEFT))
  171.       {
  172.          nexttile = layout[i+1][j];
  173.          nextattr = attributes[nexttile];
  174.          nextcross = ((nextattr&VERTICAL) + (nextattr&HORIZONTAL));
  175.          if (!visited[i+1][j] || (nextcross && (visited[i+1][j] != HORIZONTAL)))
  176.          {
  177.             if (right && nextattr&LEFT)
  178.             {
  179.                found = TRUE;
  180.                path[index++] = RIGHT;
  181.                i++;
  182.                visited[i][j] = HORIZONTAL;
  183.                x2 = i*16 + 10;
  184.                if (vertical)
  185.                  x1 += 9;
  186.                if (nextattr&VERTICAL)
  187.                  x2 -= 9;
  188.             }
  189.          }
  190.       }
  191.  
  192.       /* check UP */
  193.  
  194.       if (j > 0 && !found && !(path[index-1] == BOTTOM))
  195.       {
  196.          nexttile = layout[i][j-1];
  197.          nextattr = attributes[nexttile];
  198.          nextcross = ((nextattr&VERTICAL) + (nextattr&HORIZONTAL));
  199.          if (!visited[i][j-1] || (nextcross && (visited[i][j-1] != VERTICAL)))
  200.          {
  201.             if (top && nextattr&BOTTOM)
  202.             {
  203.                found = TRUE;
  204.                path[index++] = TOP;
  205.                j--;
  206.                visited[i][j] = VERTICAL;
  207.                y1 = j*16 + 6;
  208.                if (nextattr&HORIZONTAL)
  209.                  y1 += 9;
  210.                if (horizontal)
  211.                  y2 -= 9;
  212.             }
  213.          }
  214.       }
  215.  
  216.       /* check down */
  217.  
  218.       if (j < MAXROWS-1 && !found && !(path[index-1] == TOP))
  219.       {
  220.          nexttile = layout[i][j+1];
  221.          nextattr = attributes[nexttile];
  222.          nextcross = ((nextattr&VERTICAL) + (nextattr&HORIZONTAL));
  223.          if (!visited[i][j+1] || (nextcross && (visited[i][j+1] != VERTICAL)))
  224.          {
  225.             if (bottom && nextattr&TOP)
  226.             {
  227.                found = TRUE;
  228.                path[index++] = BOTTOM;
  229.                j++;
  230.                visited[i][j] = VERTICAL;
  231.                y2 = j*16 + 10;
  232.                if (horizontal)
  233.                  y1 += 9;
  234.                if (nextattr&HORIZONTAL)
  235.                  y2 -= 9;
  236.             }
  237.          }
  238.       }
  239.  
  240.       /* check left */
  241.  
  242.       if (i > 0 && !found && !(path[index-1] == RIGHT))
  243.       {
  244.          nexttile = layout[i-1][j];
  245.          nextattr = attributes[nexttile];
  246.          nextcross = ((nextattr&VERTICAL) + (nextattr&HORIZONTAL));
  247.          if (!visited[i-1][j] || (nextcross && (visited[i-1][j] != HORIZONTAL)))
  248.          {
  249.             if (left && nextattr&RIGHT)
  250.             {
  251.                found = TRUE;
  252.                path[index++] = LEFT;
  253.                i--;
  254.                visited[i][j] = HORIZONTAL;
  255.                x1 = i*16 + 6;
  256.                if (nextattr&VERTICAL)
  257.                  x1 += 9;
  258.                if (vertical)
  259.                  x2 -= 9;
  260.             }
  261.          }
  262.       }
  263.  
  264.       /* adjacent tile found */
  265.  
  266.       if (found)
  267.       {
  268.          fg_setcolor(0);
  269.          fg_rect(x1,x2,y1,y2);
  270.          if (is_a_vertex(nexttile))
  271.          {
  272.             path_index = index;
  273.  
  274.             /* You are at a vertex, do a recursive function call */
  275.  
  276.             if (calc_truepath(i,j)) 
  277.                 return(TRUE);
  278.  
  279.             /* try again (vertices may have 2 or 3 paths) */
  280.  
  281.             else 
  282.             {
  283.                unfill_path(i,j,index);
  284.                path_index = index;
  285.                if (calc_truepath(i,j))
  286.                    return(TRUE);
  287.                else
  288.                {
  289.                    /* you are on the wrong path -- backtrack */
  290.  
  291.                    unfill_path(i,j,index);
  292.                }
  293.             }
  294.          }
  295.       }
  296.  
  297.       /* reached a dead end */
  298.  
  299.       else
  300.       {
  301.          n_nodes = index;
  302.          return(FALSE);
  303.       }
  304.  
  305.       /* reached end of path -- maze solved! */
  306.  
  307.       if (test_bit(nextattr,7) || test_bit(attr,7))
  308.       {
  309.          n_nodes = index;
  310.          return(TRUE);
  311.       }
  312.    }
  313. }
  314.  
  315. /****************************************************************************\
  316. *                                                                            *
  317. *  help_window -- press F1 for popup help                                    *
  318. *                                                                            *
  319. \****************************************************************************/
  320.  
  321. void help_window()
  322. {
  323.    fg_mousevis(OFF);
  324.    fg_transfer(200,599,200,389,200,389,VISUAL,HIDDEN);
  325.  
  326.    fg_setcolor(7);
  327.    fg_rect(200,599,200,389);
  328.    fg_setcolor(1);
  329.    fg_box(200,599,200,389);
  330.    center_string("Help Screen",400,220);
  331.  
  332.    fg_setcolor(0);
  333.    put_string("Use the mouse to maneuver through the maze",230,240);
  334.    put_string("from the blue square to the red square.",230,256);
  335.  
  336.    put_string("F1:",260,280);
  337.    put_string("Help",320,280);
  338.  
  339.    put_string("N:",260,300);
  340.    put_string("Next Maze",320,300);
  341.  
  342.    put_string("R:",260,320);
  343.    put_string("Recursive Solution",320,320);
  344.  
  345.    put_string("C:",260,340);
  346.    put_string("Cheat mode",320,340);
  347.  
  348.    put_string("Esc:",260,360);
  349.    put_string("Exit",320,360);
  350.  
  351.    fg_setcolor(1);
  352.    center_string("Press any key to continue",400,380);
  353.  
  354.    fg_waitkey();
  355.    fg_transfer(200,599,200,389,200,389,HIDDEN,VISUAL);
  356.    fg_mousevis(ON);
  357. }
  358.  
  359. /****************************************************************************\
  360. *                                                                            *
  361. *  intro_screen -- display copyright information, etc.                       *
  362. *                                                                            *
  363. \****************************************************************************/
  364.  
  365. void intro_screen()
  366. {
  367.    fg_mousevis(OFF);
  368.    fg_setcolor(7);
  369.    center_string("Hedge Row",400,84);
  370.    center_string("Copyright 1993 Diana Gruber. All rights reserved.",400,116);
  371.    center_string("Written with Fastgraph programmer's graphics library.",400,148);
  372.    center_string("Beta version -- source code available.",400,180);
  373.    center_string("Please wait...",400,300);
  374. }
  375.  
  376. /****************************************************************************\
  377. *                                                                            *
  378. *  is_a_vertex -- check a tile to see if it is a vertex                      *
  379. *                                                                            *
  380. \****************************************************************************/
  381.  
  382. int is_a_vertex(int tile)
  383. {
  384.    int attr;
  385.    int left,right,top,bottom;
  386.    int horizontal,vertical;
  387.  
  388.    attr = attributes[tile];
  389.  
  390.    left   = ((attr&LEFT)>0);
  391.    right  = ((attr&RIGHT)>0);
  392.    top    = ((attr&TOP)>0);
  393.    bottom = ((attr&BOTTOM)>0);
  394.  
  395.    vertical   = attr&VERTICAL;
  396.    horizontal = attr&HORIZONTAL;
  397.  
  398.    if (vertical || horizontal)
  399.       return(FALSE);
  400.  
  401.    if (left+right+top+bottom >= 3)
  402.       return(TRUE);
  403.    else
  404.       return(FALSE);
  405. }
  406.  
  407. /****************************************************************************\
  408. *                                                                            *
  409. *  load_maze -- read maze information from a file                            *
  410. *                                                                            *
  411. \****************************************************************************/
  412.  
  413. void load_maze(char *mazename)
  414. {
  415.    register int i,j;
  416.    int nrows,ncols;
  417.    int x,y,tile;
  418.    char buffer[100];
  419.  
  420.    /* open the maze file and read the maze data */
  421.  
  422.    if ((tstream = fopen(mazename,"rb")) == NULL)
  423.    {
  424.       sprintf(abort_string,"%s not found.",mazename);
  425.       abort_game();
  426.    }
  427.  
  428.    fread(&ncols,sizeof(int),1,tstream);
  429.    fread(&nrows,sizeof(int),1,tstream);
  430.  
  431.    for (i = 0; i < 50; i++)
  432.    {
  433.       fread(buffer,sizeof(char),nrows,tstream);
  434.       memcpy(&layout[i][0],buffer,37);
  435.    }
  436.    fclose(tstream);
  437.  
  438.    /* display the maze tiles */
  439.  
  440.    fg_mousevis(OFF);
  441.    for (i = 0; i < ncols; i++)
  442.    {
  443.       for (j = 0; j < nrows; j++)
  444.       {
  445.          x = i*16;
  446.          y = j*16+15;
  447.          tile = layout[i][j];
  448.          put_tile(tile,x,y);
  449.       }
  450.    }
  451. }
  452.  
  453. /****************************************************************************\
  454. *                                                                            *
  455. *  put_tile -- transfer a maze tile from the hidden page to the visual page  *
  456. *                                                                            *
  457. \****************************************************************************/
  458.  
  459. void put_tile(int tile,int x,int y)
  460. {
  461.    int x1,x2,y1,y2;
  462.  
  463.    x1 = (tile%20) * 16;
  464.    x2 = x1+15;
  465.    y1 = (tile/20) * 16;
  466.    y2 = y1+15;
  467.  
  468.    fg_tcxfer(x1,x2,y1,y2,x,y,HIDDEN,VISUAL);
  469. }
  470.  
  471. /****************************************************************************\
  472. *                                                                            *
  473. *  run_maze -- this is where all the user interaction happens                *
  474. *                                                                            *
  475. \****************************************************************************/
  476.  
  477. void run_maze()
  478. {
  479.    unsigned char key,aux;
  480.    register int i,j;
  481.    int solution;
  482.    int xmouse,ymouse,buttons;
  483.    int tile,attr;
  484.    int x1,x2,x3,x4;
  485.    int y1,y2,y3,y4;
  486.    int xmin,xmax,ymin,ymax;
  487.    int old_xmin,old_xmax,old_ymin,old_ymax;
  488.    int old_xmouse,old_ymouse;
  489.    int left,right,top,bottom;
  490.    int horizontal,vertical;
  491.    int direction;
  492.    int old_i,old_j;
  493.    int old_tile, old_attr;
  494.    int norect;
  495.  
  496.    fg_mousevis(ON);
  497.  
  498.    old_xmin = 0; old_xmax = 0;
  499.    old_ymin = 0; old_ymax = 0;
  500.  
  501.    solution = FALSE;
  502.  
  503.    fg_mouselim(0,799,0,599);
  504.    fg_mousemov(20,8);
  505.    old_i = 1;
  506.    old_j = 0;
  507.    direction = VERTICAL;
  508.  
  509.    fg_mousepos(&old_xmouse,&old_ymouse,&buttons);
  510.  
  511.    while(1)
  512.    {
  513.       fg_intkey(&key,&aux);
  514.       if (key == 27)
  515.          quit_graphics();
  516.       else if (key == 'n' || key == 'N')
  517.          return;
  518.       else if (aux == F1)
  519.          help_window();
  520.       else if (key == 'r' || key == 'R')
  521.       {
  522.          fg_mousevis(OFF);
  523.          calc_truepath(1,0);
  524.          fg_getkey(&key,&aux);
  525.          if (key == 27)
  526.             quit_graphics();
  527.          return;
  528.       }
  529.       else if (key == 'c' || key == 'C')
  530.       {
  531.          solution = !solution;
  532.          if (solution)
  533.             fg_setrgb(7,25,25,63);
  534.          else
  535.             fg_setrgb(7,63,63,63);
  536.       }
  537.  
  538.       fg_mousepos(&xmouse,&ymouse,&buttons);
  539.       i = xmouse/16;
  540.       j = ymouse/16;
  541.  
  542.       if (i != old_i)
  543.          direction = HORIZONTAL;
  544.       else if (j != old_j)
  545.          direction = VERTICAL;
  546.  
  547.       tile = layout[i][j];
  548.       attr = attributes[tile];
  549.  
  550.       x1 = i*16-1;
  551.       x2 = x1+7;
  552.       x3 = x1+11;
  553.       x4 = MIN(x1+17,799);
  554.       x1 = MAX(i*16-1,0);
  555.  
  556.       y1 = j*16-1;
  557.       y2 = y1+7;
  558.       y3 = y1+11;
  559.       y4 = MIN(y1+17,599);
  560.       y1 = MAX(j*16-1,0);
  561.  
  562.       left       = attr&LEFT;
  563.       right      = attr&RIGHT;
  564.       top        = attr&TOP;
  565.       bottom     = attr&BOTTOM;
  566.       vertical   = attr&VERTICAL;
  567.       horizontal = attr&HORIZONTAL;
  568.  
  569.       if (horizontal || vertical)
  570.       {
  571.          if (direction == HORIZONTAL)
  572.          {
  573.             top = FALSE; bottom = FALSE;
  574.          }
  575.          else if (direction == VERTICAL)
  576.          {
  577.             left = FALSE; right = FALSE;
  578.          }
  579.       }
  580.  
  581.       /* calculate extents of mouse limits */
  582.  
  583.       if (right && xmouse > x2)
  584.       {
  585.          if (i == MAXCOLS-1 || !(attributes[layout[i+1][j]]&LEFT))
  586.             xmax = x3;
  587.          else
  588.             xmax = x4;
  589.       }
  590.       else
  591.          xmax = x3;
  592.  
  593.       if (left && xmouse < x3)
  594.       {
  595.          if (i == 0 || !(attributes[layout[i-1][j]]&RIGHT))
  596.             xmin = x2;
  597.          else
  598.             xmin = x1;
  599.       }
  600.       else
  601.          xmin = x2;
  602.  
  603.       if (bottom && ymouse > y2)
  604.       {
  605.          if (j == MAXROWS-1 || !(attributes[layout[i][j+1]]&TOP))
  606.             ymax = y3;
  607.          else
  608.             ymax = y4;
  609.       }
  610.       else
  611.          ymax = y3;
  612.  
  613.       if (top && ymouse < y3)
  614.       {
  615.          if (j == 0 || !(attributes[layout[i][j-1]]&BOTTOM))
  616.             ymin = y2;
  617.          else
  618.             ymin = y1;
  619.       }
  620.       else
  621.          ymin = y2;
  622.  
  623.       /* correct for diagonals - upper left */
  624.  
  625.       if (xmin == x1 && ymin == y1)
  626.       {
  627.          if (xmouse <= x2)
  628.             ymin = y2 - 3;
  629.          else
  630.             xmin = x2 - 3;
  631.       }
  632.  
  633.       /* upper right */
  634.  
  635.       if (xmax == x4 && ymin == y1)
  636.       {
  637.          if (xmouse >= x3)
  638.             ymin = y2 - 3;
  639.          else
  640.             xmax = x3 + 3;
  641.       }
  642.  
  643.       /* lower left */
  644.  
  645.       if (xmin == x1 && ymax == y4)
  646.       {
  647.          if (xmouse <= x2)
  648.             ymax = y3 + 3;
  649.          else
  650.             xmin = x2 - 3;
  651.       }
  652.  
  653.       /* lower right */
  654.  
  655.       if (xmax == x4 && ymax == y4)
  656.       {
  657.          if (xmouse >= x3)
  658.             ymax = y3 + 3;
  659.          else
  660.             xmax = x3 + 3;
  661.       }
  662.  
  663.       fg_mouselim(xmin,xmax,ymin,ymax);
  664.  
  665.       /* draw the path only if the mouse has moved*/
  666.  
  667.       if (xmouse != old_xmouse || ymouse != old_ymouse)
  668.       {
  669.  
  670.          /* going right */
  671.  
  672.          norect = FALSE;
  673.          if (old_i < i)
  674.          {
  675.             old_tile = layout[i-1][j];
  676.             old_attr = attributes[old_tile];
  677.             if (old_attr&VERTICAL)
  678.                xmin = x1;
  679.             else
  680.                xmin = x1 - 8;
  681.             if (vertical)
  682.                xmax = x2 - 5;
  683.             else
  684.                xmax = x3;
  685.          }
  686.  
  687.          /* going left */
  688.  
  689.          else if (old_i > i)
  690.          {
  691.             old_tile = layout[i+1][j];
  692.             old_attr = attributes[old_tile];
  693.             if (old_attr&VERTICAL)
  694.                xmax = x4 + 1;
  695.             else
  696.                xmax = x4 + 8;
  697.             if (vertical)
  698.                xmin = x3 + 5;
  699.             else
  700.                xmin = x2;
  701.          }
  702.  
  703.          /* no horizontal movement */
  704.  
  705.          else
  706.          {
  707.             xmin = x2;
  708.             xmax = x3;
  709.          }
  710.  
  711.  
  712.          /* going down */
  713.  
  714.          if (old_j < j)
  715.          {
  716.             old_tile = layout[i][j-1];
  717.             old_attr = attributes[old_tile];
  718.             if (old_attr&HORIZONTAL)
  719.                ymin = y1;
  720.             else
  721.                ymin = y1 - 8;
  722.             if (horizontal)
  723.                ymax = y2 - 5;
  724.             else
  725.                ymax = y3;
  726.          }
  727.  
  728.          /* going up */
  729.  
  730.          else if (old_j > j)
  731.          {
  732.             old_tile = layout[i][j+1];
  733.             old_attr = attributes[old_tile];
  734.             if (old_attr&HORIZONTAL)
  735.                ymax = y4 + 1;
  736.             else
  737.                ymax = y4 + 8;
  738.             if (horizontal)
  739.                ymin = y3 + 5;
  740.             else
  741.                ymin = y2;
  742.          }
  743.  
  744.          /* no vertical movement */
  745.  
  746.          else
  747.          {
  748.             ymin = y2;
  749.             ymax = y3;
  750.          }
  751.          if (i == old_i && j == old_j)
  752.             norect = TRUE;
  753.  
  754.          if (!norect)
  755.          {
  756.             fg_mousevis(OFF);
  757.             fg_setcolor(7);
  758.             if (old_xmin > 0) fg_rect(old_xmin,old_xmax,old_ymin,old_ymax);
  759.             fg_setcolor(3);
  760.             fg_rect(xmin,xmax,ymin,ymax);
  761.             fg_mousevis(ON);
  762.  
  763.             old_xmin = xmin; old_xmax = xmax;
  764.             old_ymin = ymin; old_ymax = ymax;
  765.          }
  766.       }
  767.  
  768.       old_xmouse = xmouse;
  769.       old_ymouse = ymouse;
  770.       old_i = i;
  771.       old_j = j;
  772.    }
  773. }
  774.  
  775. /****************************************************************************\
  776. *                                                                            *
  777. * test_bit -- used to check for tile attributes                              *
  778. *                                                                            *
  779. \****************************************************************************/
  780.  
  781. test_bit(int num,int bit)
  782. {
  783.    return((_rotr(num,bit))&1);
  784. }
  785.  
  786. /****************************************************************************\
  787. *                                                                            *
  788. *  unfill_path -- change the color back to white                             *
  789. *                                                                            *
  790. \****************************************************************************/
  791.  
  792. int unfill_path(int i,int j,int n)
  793. {
  794.    int index;
  795.    int x1,x2,y1,y2;
  796.    int tile;
  797.    int attr;
  798.  
  799.    fg_setcolor(7);
  800.    for (index = n; index < n_nodes; index++)
  801.    {
  802.       x1 = i*16 + 6;
  803.       x2 = x1 + 4;
  804.       y1 = j*16 + 6;
  805.       y2 = y1 + 4;
  806.  
  807.       switch(path[index])
  808.       {
  809.          case LEFT:
  810.             tile = layout[i][j];
  811.             attr = attributes[tile];
  812.             if (attr&VERTICAL)
  813.               x2 -= 9;
  814.  
  815.             i--;
  816.             x1 = i*16 + 6;
  817.  
  818.             tile = layout[i][j];
  819.             attr = attributes[tile];
  820.             if (attr&VERTICAL)
  821.                x1 += 9;
  822.  
  823.             break;
  824.          case RIGHT:
  825.             tile = layout[i][j];
  826.             attr = attributes[tile];
  827.             if (attr&VERTICAL)
  828.                x1 += 9;
  829.  
  830.             i++;
  831.             x2 = i*16 + 10;
  832.  
  833.             tile = layout[i][j];
  834.             attr = attributes[tile];
  835.             if (attr&VERTICAL)
  836.                x2 -= 9;
  837.  
  838.             break;
  839.          case TOP:
  840.             tile = layout[i][j];
  841.             attr = attributes[tile];
  842.             if (attr&HORIZONTAL)
  843.               y2 -= 9;
  844.  
  845.             j--;
  846.             y1 = j*16 + 6;
  847.  
  848.             tile = layout[i][j];
  849.             attr = attributes[tile];
  850.             if (attr&HORIZONTAL)
  851.               y1 += 9;
  852.  
  853.             break;
  854.          case BOTTOM:
  855.             tile = layout[i][j];
  856.             attr = attributes[tile];
  857.             if (attr&HORIZONTAL)
  858.               y1 += 9;
  859.  
  860.             j++;
  861.             y2 = j*16 + 10;
  862.  
  863.             tile = layout[i][j];
  864.             attr = attributes[tile];
  865.             if (attr&HORIZONTAL)
  866.               y2 -= 9;
  867.  
  868.             break;
  869.          default:
  870.             return(FALSE);
  871.       }
  872.       fg_rect(x1,x2,y1,y2);
  873.    }
  874.    return(TRUE);
  875. }
  876.